--窗体里边注册事件 窗口关闭的时候要移除
--self:registerMsg(MsgType.SC_LOGIN ,handler(self,self.receiveHandler));
--self:removeRegister(MsgType.SC_LOGIN ,handler(self,self.receiveHandler));
local ProtoMgr = class("ProtoMgr");
local SOCKET = {LUA_TCP_SOCKET = 0,LUA_WEB_SOCKET = 1};
local curSocket = SOCKET.LUA_WEB_SOCKET;
local WebSockets = nil;
local scnet = nil;
if curSocket ==  SOCKET.LUA_TCP_SOCKET then
    scnet = require(SCRIPTS_DIR .. ".network.Scnet");
else
    WebSockets = require(SCRIPTS_DIR .. ".network.WebSockets");
end

function ProtoMgr:ctor()
    self._listenerList = {};
end

function ProtoMgr:connect(host,portORpro)
    if curSocket ==  SOCKET.LUA_TCP_SOCKET then
        self:connectTcpSocket(host,portORpro);
        return;
    end
    self:initWebSocket();
    self:connectWebSocket(host,portORpro);
end


function ProtoMgr:initWebSocket()
    self.messageType = WebSockets.TEXT_MESSAGE;
    self.websocket = nil;
    self.socketIsOk = false;
end

function ProtoMgr:connectTcpSocket(host,port)
    scnet.init();
    scnet.connect(host,port,true);
end


function ProtoMgr:connectWebSocket(host,protocol)
    if self.websocket then return end
    self.websocket = WebSockets.new(host,protocol);
    self.websocket:addEventListener(WebSockets.OPEN_EVENT, handler(self, self.onOpen));
    self.websocket:addEventListener(WebSockets.MESSAGE_EVENT, handler(self, self.onMessage));
    self.websocket:addEventListener(WebSockets.CLOSE_EVENT, handler(self, self.onClose));
    self.websocket:addEventListener(WebSockets.ERROR_EVENT, handler(self, self.onError));
end

function ProtoMgr:closeSocket()
    if curSocket ==  SOCKET.LUA_TCP_SOCKET then
        scnet.onExitSocket();
        return;
    end
    if self.websocket then
        self.websocket:close();
    end
end

function ProtoMgr:onOpen(event)
    mgrs.log:printNotice("WebSocketMgr:onOpen")
    self.socketIsOk = true;
    mgrs.event:dispatchEvent({name = enums.Event.WebSocketOpen});
end

function ProtoMgr:onMessage(event)
    if WebSockets.BINARY_MESSAGE == event.messageType then
        mgrs.log:printNotice("receive binary msg: len = %s, binary = %s", string.len(event.message), bin2hex(event.message));
    else
        mgrs.log:printNotice("收到数据:%s",event.message)
        local message = json.decode(event.message);
        self:disPatchProto(message.msgid,message);
    end
end

function ProtoMgr:onClose(event)
    mgrs.log:printNotice("WebSocketMgr:onClose");
    self.websocket = nil
    self.socketIsOk = false;
    mgrs.event:dispatchEvent({name = enums.Event.WebSocketClose});
end

function ProtoMgr:onError(event)
    mgrs.log:printWarn("WebSocket onError %s", event.error)
    self.websocket = nil
    self.socketIsOk = false;
end

function ProtoMgr:send(data,msgid)
    if curSocket ==  SOCKET.LUA_TCP_SOCKET then
        scnet.send(msgid,data);
    end
    if self.websocket and self.socketIsOk then
        if type(data) == "table" then
            data = json.encode(data);
        elseif type(data) == "number" then
            data = json.encode({msgid = data});
        end
        mgrs.log:printNotice("发送数据:%s",data);
        self.websocket:send(data,self.messageType);
    end
end


-- 注册消息
-- 注册之后 接受到服务器消息之后进行广播，谁注册，谁响应
function ProtoMgr:registerMsg(msgid,callBack)
    self._listenerList[msgid] = self._listenerList[msgid] or {};
    local isExist = self:registerCbkIsExit(msgid,callBack);
    if not isExist then
        table.insert(self._listenerList[msgid],callBack);
    else
        mgrs.log:printWarn("%s 已经注册啦",msgid);
    end
end
-- 移除注册消息
function ProtoMgr:removeRegister( msgid,callBack )
    if self._listenerList[msgid] then
        for k,v in pairs(self._listenerList[msgid]) do
            if v == callBack then
                table.remove(self._listenerList[msgid],k);
                break;
            end
        end
    end
end
-- 移除所有注册消息
function ProtoMgr:removeAllMsg()
    self._listenerList = nil;
    self._listenerList = {};
end

-- 接受消息
-- 派发事件
function ProtoMgr:disPatchProto(msgid,data)
    if self._listenerList[msgid] and #self._listenerList[msgid] ~= 0 then
        for k,v in pairs(self._listenerList[msgid]) do
            v(data);
        end
        mgrs.log:printDebug("%d 派发成功！",msgid);
    else
        mgrs.log:printWarn("%d 没有被监听！！！！",msgid);
    end
end

function ProtoMgr:registerCbkIsExit( msgid,callBack )
    for k,v in pairs(self._listenerList[msgid]) do
        if v == callBack then
            return true;
        end
    end
    return false;
end


local function bin2hex(binary)
    local t = {}
    for i = 1, string.len(binary) do
        t[#t + 1] = string.format("0x%02x", string.byte(binary, i))
    end
    return table.concat(t, " ")
end


mgrs.proto = nil;
mgrs.singleClass(mgrs,ProtoMgr,"proto");